package tpoo.common.utils.passiveOperations;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import tpoo.common.dto.model.users.UserDTO;
import tpoo.common.services.utils.ServiceConstants;
import tpoo.common.utils.Parameters;
import tpoo.common.utils.UserSession;

/**
 * Operaciones que ocurren en el cliente, y no son originadas por él si no por otro usuario o el mismo servidor
 * @author diemar
 *
 */
public abstract class PassiveOperation implements ServiceConstants, Serializable{
	
	private static final String NOT_IMPLEMENTED_YET = "Not Implemented Yet";

	//TODO: Analizar si vale la pena o poner como static y que solo se nombre genéricamente
	//Hecho así para que el logger se pueda crear dependiendo del la subclase
	private Log logger = LogFactory.getLog(this.getClass());
	
	private Parameters parameters=null;
	
	public PassiveOperation(Parameters parameters) {
		this.parameters = parameters;
	}

	//La Operación no necesita parámetros
	public PassiveOperation(){
		getLogger().debug("new "+this.getClass().getCanonicalName()+"()");
	}
	
	/**
	 * Cada subclase debe implementar el método execute
	 * @throws Exception
	 */
	public abstract void execute() throws Exception;

	private void setLogger(Log logger) {
		this.logger = logger;
	}

	protected Log getLogger() {
		return logger;
	}
	
	protected void notImplementedYet() {
		RuntimeException e = new RuntimeException(NOT_IMPLEMENTED_YET);
		this.getLogger().error(NOT_IMPLEMENTED_YET,e);
		throw e;
	}
	
	@Override
	public String toString() {
		List<Object> actualParams=this.getParameters();
		StringBuffer str = new StringBuffer(this.getClass().getCanonicalName()+".execute(");
		for (Object param : actualParams)
			str.append(param).append(", ");
		if (!actualParams.isEmpty())
			str.replace(str.length()-2, str.length(), ")"); //saco el último espacio y la última coma
		else
			str.append(")");
		return str.toString(); 
	}
	
	List<Object> actualParameters = new ArrayList<Object>();
	protected List<Object> getParameters(){	
		return actualParameters;
	}
	
	PassiveOperation addParameter(Object parameterValue){
		actualParameters.add(parameterValue);
		return this;
	}
	
	protected UserDTO getLoggedUser(){
		return UserSession.getInstance().getUser();
	}
}
